home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 331 / gemfst14 / gemxtend.doc < prev    next >
Text File  |  1990-07-20  |  22KB  |  460 lines

  1. **************************************************************************
  2. *
  3. * GEMXTEND.DOC - Descriptions of extensions made to GEM bindings since
  4. *                the original TOS 1.0 release.
  5. *
  6. *  05/26/90    - v.4
  7. *                Included documentation on the new calling standard,
  8. *                and the bindings that currently support it:
  9. *                   evnx_multi()
  10. *                   frmx_center()
  11. *                   winx_get()
  12. *                   winx_calc()
  13. *
  14. *  09/06/89    - v1.3
  15. *                This document is new with this release, and contains
  16. *                revisions through TOS 1.4.
  17. **************************************************************************
  18.  
  19. This document is divided into two sections.  Section 1 documents the 
  20. changes and additions Atari has made to the GEM routines in TOS.  Section 2 
  21. documents alternate calling standards to the existing functions.  These
  22. alternate bindings provide more efficient ways to call AES functions.
  23.  
  24.  
  25. **************************************************************************
  26. *
  27. * Section 1 - Changes Atari has made to GEM/TOS.
  28. *
  29. **************************************************************************
  30.  
  31. This section describes extensions Atari has made to TOS/GEM since the
  32. original TOS 1.0 operating system.  When Atari adds new VDI/AES functions,
  33. appropriate bindings will be created and documented here.  Note that some
  34. of the functions listed here have been available since TOS 1.0, but Atari
  35. neglected to document them.  The title bar for each function lists the
  36. first TOS version that supported the function.  Other functions have 
  37. backwards compatibility built into the GEMFAST binding so that they will 
  38. work correctly on all TOS versions (these are noted in the title bars too).
  39.  
  40. *--------------------------------------------------------------------------
  41. * About TOS 1.4...
  42. *--------------------------------------------------------------------------
  43.  
  44.  The TOS 1.4 pre-release notes contain documentation for the following:
  45.  
  46.    form_error    form_alert    shel_write    shel_get    shel_put  
  47.    fsel_exinput  wind_new
  48.  
  49.  Of these, the form_error/alert and shel_???? docs seem to be just a 
  50.  clarification of the docs without any functional changes.
  51.  
  52.  The wind_new and fsel_exinput functions are new with TOS 1.4.
  53.  
  54. ;-------------------------------------------------------------------------
  55. ; wind_new                    TOS 1.4
  56. ;-------------------------------------------------------------------------
  57.  
  58.   void wind_new();
  59.  
  60.   The 'wind_new' function is for doing a major cleanup after a GEM 
  61.   application.  It closes & deletes all windows, flushes all the windows'
  62.   buffers (of redraw msgs, I presume), clears the wind_update flag, and
  63.   restores ownership of the mouse to the system (END_MCTRL I presume). The
  64.   documentation is not clear on whether this function should be used by
  65.   an application that wants to shut down everything quickly, or whether it
  66.   is intended for a shell's use in cleaning up after an application exits.
  67.   I tend to suspect the latter, and I think this function was developed 
  68.   because shell writers all begged Atari to provide something that could
  69.   clean up after an application the way the desktop does.
  70.  
  71. ;-------------------------------------------------------------------------
  72. ; fsel_exinput                TOS 1.4 (binding compatible with 1.0 and up)
  73. ;-------------------------------------------------------------------------
  74.  
  75.   Full 1.4 emulation...
  76.  
  77.   status = fsel_exinput(in_path, in_sel, &exitbtn, prompt_text);
  78.   
  79.    (status and exitbtn are 16-bit ints, others are char *).
  80.    
  81.  This routine is functionally equivelent to fsel_input, except that it
  82.  also allows you to specify a prompt string of up to 30 characters to be
  83.  displayed along with the file selector.  While the function is new with
  84.  TOS 1.4, the AESFAST bindings support it in all versions via a routine
  85.  which checks the AES version number and simulates the actions of
  86.  fsel_exinput by using fsel_input and objc_draw.  If running under
  87.  TOS 1.4, the system will display your prompt text in place of the words
  88.  'FILE SELECTOR' inside the fsel box.  If running under pre-TOS 1.4, the
  89.  simulation routines place the prompt text in a box which appears 
  90.  between the menu bar and the fsel box.
  91.  
  92.  Other TOS 1.4 changes to the fsel routines that this routine supports 
  93.  via simulation when running on pre-TOS 1.4 systems...
  94.  
  95.   - The file selector now allows you to edit the pathname and hit RETURN
  96.     without exiting the dialog.  If you edit the filename and hit <CR>,
  97.     you will exit as if you clicked on OK.
  98.   - If the initial pathname has a leading '\', it will be appended to the
  99.     end of the current default drive and path, and the entire resulting
  100.     string will be returned if the user exits via OK or <CR>.
  101.   - The current default drive and path are preserved, and the contents
  102.     of the current DTA are preserved.  Only the default path on the 
  103.     default drive is saved with the simulation software. If the user
  104.     changes devices during file selection, the default path on all devices
  105.     may  be changed except for the device that was the default when 
  106.     fsel_exinput was called.
  107.  
  108.   The executable code for the fsel_exinput binding is big -- about 800
  109.   bytes.  Also, it uses about 350 bytes of stack space during the call.
  110.   Still, having a prompted file selector that works correctly on all
  111.   machines will lend a touch of class to your application (IMHO).
  112.  
  113.   Note that all of the above fsel ehancements which are supported by the
  114.   simulation on pre-TOS 1.4 systems are supported ONLY if you call
  115.   fsel_exinput; if you call fsel_input on a pre-1.4 system the default
  116.   path et. al. will behave as they always have. (Hint: USE exinput).
  117.  
  118. ;-------------------------------------------------------------------------
  119. ; fsel_smallexinput           TOS 1.4 (binding compatible with 1.0 and up)
  120. ;-------------------------------------------------------------------------
  121.  
  122.   Prompting emulation only...
  123.  
  124.   This function has calling parameters identical to fsel_exinput() (see
  125.   above), but it's behavior (return values, etc) is identical to that of
  126.   fsel_input() (the original).  This function will call the real 'exinput'
  127.   routine if on TOS 1.4, but if on an earlier version it emulates only the
  128.   prompting of 'exinput', it does not save the path or DTA, or handle <CR>
  129.   correctly, or any of the other nice TOS 1.4 features.  On the other hand,
  130.   it's only half as big as the full emulator for fsel_exinput(), so it's
  131.   handy for accessories and other small-memory applications.  (It will add
  132.   about 450 bytes to your program, as opposed to 800).        
  133.   
  134.   I'd like to recommend that you do not code calls to fsel_smallexinput()
  135.   directly in your program.  Instead, just code fsel_exinput(), and at the
  136.   top of your C source, code:
  137.   
  138.     #define fsel_exinput fsel_smallexinput
  139.  
  140.   and let the C compiler handle the rest for you.  This ought to keep your
  141.   code compatible many years into the future...
  142.  
  143. ;-------------------------------------------------------------------------
  144. ; fsel_14input              TOS 1.4 (binding compatible with 1.0 and up)
  145. ;-------------------------------------------------------------------------
  146.  
  147.   No emulation.
  148.  
  149.   This function has calling parameters identical to fsel_exinput() (see
  150.   above).  However, it makes no attempt to emulate any of the 1.4 exinput
  151.   features.  Basically, if running on TOS 1.4, fsel_exinput is called.  If
  152.   running on a pre-1.4 system, the prompt string is thrown away, and the
  153.   normal file selector is called.  This binding is very small compared to
  154.   other (emulation mode) exinput bindings.
  155.   
  156.   Again, it is best to access this function through a #define statement:
  157.   
  158.     #define fsel_exinput fsel_14input
  159.  
  160. | This function was added with v1.4.
  161.  
  162. ;-------------------------------------------------------------------------
  163. ; shel_get / shel_put         TOS 1.0
  164. ;-------------------------------------------------------------------------
  165.  
  166.   status = shel_get(char *bufadr, int buflen)
  167.   status = shel_put(char *bufadr, int buflen)
  168.   
  169.           These functions read and write the desktop's internal buffer
  170.           which holds a copy of the DESKTOP.INF file.  The buffer holds
  171.           an exact image of the file, in plain ASCII text.  If 'status'
  172.           is returned as zero, an error occurred.  The Atari docs say that
  173.           the buffer should never exceed 1024 bytes, but I've been told
  174.           that it *can* in fact exceed this length.
  175.  
  176. ;-------------------------------------------------------------------------
  177. ; form_keybd                  TOS 1.0
  178. ;-------------------------------------------------------------------------
  179.  
  180.   keyret = form_keybd(tree, object, nxtobject, thechar, &nxtobject, &thechar);
  181.   
  182.      (All values are 16-bit words, except 'tree', which is OBJECT *).
  183.      
  184.      The form_keybd routine acts as a filter on character input.
  185.      When it  recognizes a control  character,  it processes
  186.      it and zeroes the keyboard word.  Other chararacters can be
  187.      passed on to objc_edit to be inserted in the editable object.  
  188.      If the routine returns a zero, a default object is selected (<CR>).
  189.      (Hints:  If 'nxtobject' is not equal to 'object' after this call,
  190.      form_keybd() has detected a TAB or ARROW key to move to the next
  191.      edit field, so call objc_edit(..., EDEND) for the current field,
  192.      as long as nxtobject is non-zero.  If 'thechar' comes back non-zero,
  193.      pass it to objc_edit(..., EDCHAR).  If this doesn't make sense, get
  194.      the Tim Oren articles and make your own interpretations.)
  195.  
  196. ;-------------------------------------------------------------------------
  197. ; form_button                 TOS 1.0
  198. ;-------------------------------------------------------------------------
  199.  
  200.   btnret = form_button(tree, object, clicks, &nxtobject);
  201.   
  202.      (All values are 16-bit words, except 'tree', which is OBJECT *).
  203.           
  204.      I can't tell you as much about this one.  This routine handles an
  205.      already-occurred mouse button event.  It handles changing the 
  206.      selected object into reverse video.  It (presumably) handles radio
  207.      buttons. 'object' is the index of the object the mouse is over, so
  208.      I presume have have to call objc_find() first to get this. 'nxtobject'
  209.      is the new selected object index.  If the routine returns a zero,
  210.      a default or exit object was selected.
  211.  
  212.  
  213. **************************************************************************
  214. *
  215. * Section 2 - An alternate calling standard, and supporting bindings...
  216. *
  217. **************************************************************************
  218.  
  219. BACKGROUND
  220.  
  221. The calling standard for AES functions defined and documented by DRI was
  222. defined for ease of use in C programming, but it does not lend itself to
  223. particularly efficient code generation.  For example, the wind_get() call
  224. can be used to return many different types of values, so DRI defined the
  225. function as taking pointers to 4 separate output fields.  However, one of 
  226. most common functions for wind_get() is to return information about window
  227. rectangles; the values are returned in typical GRECT order. 
  228.  
  229. In the old days, a call of this type was often coded as:
  230.  
  231.     wind_get(wi_handle, WF_CURRXYWH, &x, &y, &w, &h);
  232.     
  233. As GEM coding techniques have become more sophisticated, people have found
  234. that it makes more sense to keep xywh values in GRECT structures instead of
  235. in discrete variables.  This leads to the rather cumbersome construct:
  236.  
  237.     wind_get(wi_handle, WF_CURRXYWH, 
  238.                 &windrect.g_x, &windrect.g_y,
  239.                 &windrect.g_w, &windrect.g_h);
  240.                 
  241. When ideally, one would prefer to code:
  242.  
  243.     wind_get(wi_handle, WF_CURRXYWH, &windrect);
  244.     
  245. This makes a huge difference in runtime performance.  When the binding for
  246. the original wind_get() routine is called, it has no idea whether discrete
  247. (possibly discontiguous) addresses are passed, so it must build a temporary
  248. output array on the stack in which the AES can pass return values.  Upon 
  249. return from the AES, the binding must copy each of the four return values
  250. back to the caller's memory, using the 4 individual pointers specified.
  251. Using the alternate calling standard, the binding can simply pass the AES
  252. the GRECT pointer specified in the call, and the AES can place the returned
  253. values directly into the caller's memory, avoiding intermediate arrays.
  254. Also, the C compiler only has to stack one address when setting up the call.
  255.  
  256. STANDARDS
  257.  
  258. Because it is not possible to have one function name to handle both types
  259. of calling standards, I have choosen to implement the alternate bindings
  260. using similar names, with an 'x' to indicate it is one of the extended
  261. bindings.  Thus, wind_get() would be called when discrete addresses are
  262. passed, and winx_get() would be called when a single pointer is passed.
  263.  
  264. There will be a certain amount of schizophrenia in the alternate binding
  265. standards.  Some functions (such as evnx_multi) will take all input and
  266. output values in a single consolidated structure.  Others will pass 
  267. discrete input values, but take the return values in a structure, or
  268. vice versa.  I will try to use common sense when making such decisions;
  269. what I want to avoid is the VDI mess.  With VDI calls, you have to load
  270. *everything* into an array, even when it doesn't seem to make sense to 
  271. do so.  I think VDI coding is very tedious for this reason, and I'm going
  272. to try to avoid that with the alternate AES bindings.
  273.  
  274. As an aside:  I've heard rumours that Tim Oren defined an entire alternate
  275. calling structure for the AES under the name GEMX.  Unfortunately, I can't
  276. find out anything about it except that it 'may exist'.  Therefore, nothing
  277. in my alternate calling standards are going to correspond to his, except
  278. by accident.  If anybody has more info on GEMX, I'd love to learn about it.
  279.  
  280. IMPLEMENTATION
  281.  
  282. I had planned to write the entire set of alternate bindings and release
  283. them as GemFast v2.0.  I've been planning that for months, and it isn't
  284. working out.  Therefore, beginning with v1.4, I'm releasing things as I 
  285. go.  As of 1.4, there are only a couple of these extended bindings 
  286. available.
  287.  
  288. X-STRUCTURES
  289.  
  290. Where custom data structures are needed by an alternate binding, the
  291. structures will be documented with the binding(s) that use them.  All such
  292. structures are defined in the GEMFAST.H header file.
  293.  
  294. ;-------------------------------------------------------------------------
  295. ; evnx_multi    - Alternate for evnt_multi.
  296. ;-------------------------------------------------------------------------
  297.  
  298.     int evnx_multi(XMULTI *xm);
  299.     
  300.     This binding takes a single parm, a pointer to an XMULTI structure.  It 
  301.     returns an integer, which is a bit mask of events which occurred (the
  302.     same value returned by evnt_multi).  This mask is also returned in 
  303.     the mwhich element of the XMULTI structure.
  304.     
  305.     All of the values normally passed to evnt_multi are included in the
  306.     XMULTI structure.  All of the output values are returned in the XMULTI
  307.     structure, including messages in the message buffer, which is the 1st
  308.     eight words of the XMULTI structure.
  309.     
  310.     The XMULTI structure is defined as follows:
  311.     
  312.         typedef struct xmulti {         
  313.             int     msgbuf[8];          /* Message buffer               */
  314.             int     mflags;             /* Mask of events to wait for   */
  315.             int     mbclicks,           /* Button clicks to wait for    */
  316.                     mbmask,             /* Which buttons to wait for    */
  317.                     mbstate;            /* Button state to wait for     */
  318.             int     mm1flags;           /* M1 rect: wait for in/out flag*/
  319.             GRECT   mm1rect;            /* M1 rect: xywh coordinates    */
  320.             int     mm2flags;           /* M2 rect: wait for in/out flag*/
  321.             GRECT   mm2rect;            /* M2 rect: xywh coordinates    */
  322.             int     mtlocount,          /* Timer count low value        */
  323.                     mthicount;          /* Timer count high value       */
  324.             int     mwhich,             /* Mask of events that occurred */
  325.                     mmox,               /* Mouse x at time of event     */
  326.                     mmoy,               /* Mouse y at time of event     */
  327.                     mmobutton,          /* Mouse buttons at event       */
  328.                     mmokstate,          /* Keystate at event            */
  329.                     mkreturn,           /* Key pressed at event         */
  330.                     mbreturn;           /* Times buttons was clicked    */
  331.         } XMULTI;                       
  332.  
  333.     It is most efficient to code the XMULTI structure as a local variable
  334.     of the function that uses it, although it can be defined as a global
  335.     or static variable.  A simple, typical multi-handler might look like:
  336.     
  337.     multi()
  338.     {
  339.         XMULTI  xm;
  340.         int     events
  341.         
  342.         /* 
  343.          * set up static portions of xm structure...
  344.          */
  345.  
  346.         xm.mflags = MU_TIMER | MU_MESAG | MU_BUTTON;
  347.         
  348.         xm.tlocount = 1000;         /* 1 second     */
  349.         xm.thicount = 0;            /* timer value  */
  350.  
  351.         xm.mbclicks = 1;            /* wait for single  */
  352.         xm.mbmask   = 1;            /* click of left    */
  353.         xm.mbstate  = 1;            /* button           */
  354.  
  355.         while (1) {
  356.  
  357.             events = evnx_multi(&xm);
  358.             
  359.             if (events & MU_BUTTON) {
  360.                 handle_button(xm.mox, xm.moy);
  361.             }
  362.  
  363.             if (events & MU_TIMER) {
  364.                 handle_timeout();
  365.             }
  366.  
  367.             if (events & MU_MESAG) {
  368.                 switch(xm.msgbuf[0]) {
  369.                   case WM_REDRAW:
  370.                     do_redraw(xm.msgbuf[3], &xm.msgbuf[4]);
  371.                     break;
  372.                   case MN_SELECTED:
  373.                     do_menuitem(xm.msgbuf[3], xm.msgbuf[4]);
  374.                     break;
  375.                 /* etc */
  376.                 }               /* end switch           */
  377.             }                   /* end if (MU_MESAG)    */
  378.         }                       /* end while(1)         */
  379.     }                           /* end multi() function */
  380.     
  381.     As can be seen in the example, this can be much more efficient than
  382.     the usual call to evnt_multi, because it is not necessary to stack
  383.     50-some bytes of info on each loop iteration.  Also, the binding for
  384.     envx_multi is *much* smaller and faster than the one for evnt_multi.
  385.     
  386. ;-------------------------------------------------------------------------
  387. ; winx_get          - Alternate for wind_get
  388. ;-------------------------------------------------------------------------
  389.  
  390.     int winx_get(int whandle, int wfield, GRECT *outrect);
  391.     
  392.     This binding takes the same 2 input parms as wind_get; the window 
  393.     handle, and a value indicating the window info to be returned.  For 
  394.     output, it takes a pointer to a GRECT structure.  The return value is
  395.     the same as for wind_get() (0 indicates error).
  396.     
  397.     Note that the pointer to the output doesn't *have* to be a GRECT 
  398.     pointer, it is more specifically a pointer to 4 contiguous words of 
  399.     storage which will hold the return values.  The only wind_get() 
  400.     functions which return more than a single value all return GRECT type
  401.     output, however.  
  402.     
  403.     If winx_get() is called with a wfield value that implies just one 
  404.     return value (WF_TOP, for example), you must be aware that EIGHT BYTES
  405.     OF MEMORY WILL BE MODIFIED at the location pointed to by the output
  406.     pointer.  (All but the first 2 bytes will be garbage, of course).
  407.     
  408.     Usage example:
  409.     
  410.         GRECT currect;
  411.         
  412.             winx_get(wi_handle, WF_CURRXYWH, &currect);
  413.             
  414. ;-------------------------------------------------------------------------
  415. ; frmx_center        - Alternate for form_center
  416. ;-------------------------------------------------------------------------
  417.  
  418.     int frmx_center(OBJECT *ptree, GRECT *outrect);
  419.  
  420.     This binding takes a pointer to an object tree (as form_center does),
  421.     and a pointer to a GRECT where the output xywh values will be returned.
  422.     The return value from the function is always 1, as for form_center.
  423.     
  424.     Example:
  425.     
  426.         GRECT treerect;
  427.         
  428.         frmx_center(ptree, &treerect);
  429.         objc_draw(ptree, R_TREE, MAX_DEPTH, treerect);
  430.  
  431. ;-------------------------------------------------------------------------
  432. ; winx_calc         - Alternate for wind_calc
  433. ;-------------------------------------------------------------------------
  434.  
  435.     int winx_calc(int type, kind, in_x, in_y, in_w, in_h, GRECT *outrect);
  436.  
  437.     This binding takes all the same input values as wind_calc, but returns
  438.     the output in a GRECT structure.  Note that although the input xywh
  439.     values are listed as discrete in the definition above, your compiler
  440.     will accept the name of a GRECT as the third parameter, and will 
  441.     stack the four values from the rectangle as discrete parms.
  442.     
  443.     The following example might be used to create a window around an
  444.     object tree...
  445.     
  446.         int   wi_kind  = MOVER | FULLER | CLOSER;
  447.         GRECT workrect;
  448.         GRECT fullrect;
  449.  
  450.         frmx_center(tree, &workrect); 
  451.         winx_calc(WC_BORDER, wi_kind, workrect, &fullrect);
  452.         wi_handle = wind_create(wi_kind, fullrect);
  453.         if (wi_handle >= 0)
  454.             wind_open(wi_handle, fullrect);
  455.  
  456.  
  457. **************************************************************************
  458. * END OF GEMXTEND DOC
  459. **************************************************************************
  460.